package cn.tannn.ops.util;

import cn.tannn.jdevelops.exception.built.BusinessException;
import cn.tannn.ops.ssh.pojo.UsePortInfo;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import lombok.extern.slf4j.Slf4j;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

import static cn.tannn.ops.util.CommandUtil.getJarNameByPid;


/**
 * 端口工具
 *
 * @author <a href="https://t.tannn.cn/">tan</a>
 * @version V1.0
 * @date 2024/12/26 14:14
 */
@Slf4j
public class PortUtil {

    /**
     * 获取端口占用详情
     *
     * @param session   {@link SSHUtil#connectionServer(String, String, String, int)}
     * @return 备份文件绝对路径(物理机)
     * @throws JSchException jsch异常
     * @throws IOException   io异常
     */
    public static List<UsePortInfo> findPortUseInfo(Session session) throws JSchException, IOException {
        ChannelExec channel = null;
        InputStream in = null;
        BufferedReader reader = null;
        try {
            // 打开 exec channel 并设置命令
            channel = (ChannelExec) session.openChannel("exec");
            channel.setCommand("ss -tulnp");

            // 获取命令输出流
            in = channel.getInputStream();
            reader = new BufferedReader(new InputStreamReader(in));

            // 连接通道
            channel.connect();

            List<UsePortInfo> output = new ArrayList<>();
            String line;
            while ((line = reader.readLine()) != null) {
                // 跳过标题行
                if (line.toLowerCase().startsWith("netid")) {
                    continue;
                }
                // 解析每一行的端口信息
                UsePortInfo usePortInfo = UsePortInfo.parsePortInfo(line);
                if (usePortInfo != null) {
                    // 如果是 Java 进程，获取 JAR 名称
                    if ("java".equals(usePortInfo.getProcess())) {
                        String jarName = getJarNameByPid(usePortInfo.getPid(), session);
                        usePortInfo.setJarName(jarName);  // 设置 JAR 文件名
                    }
                    output.add(usePortInfo);
                }
            }
            return output;
        } catch (Exception e) {
            throw new BusinessException("获取端口占用详情", e);
        } finally {
            // 关闭资源
            if (reader != null) {
                reader.close();
            }
            if (channel != null && channel.isConnected()) {
                channel.disconnect();
            }
            if(in != null){
                in.close();
            }
            SSHUtil.disconnectServer(session);
        }
    }

}
